import {Injectable} from '@angular/core';
import {RequestOptions} from '@angular/http';
import {Observable} from 'rxjs';
import {MsgResult} from '../../models/msg-result';
import {LogUtil} from '../../util/log-util';
import {HttpClient, HttpErrorResponse, HttpHeaders, HttpParams} from '@angular/common/http';
import {HttpClientInterface} from './http-client-interface';

/**
 * Created by duqunxing on 2017/3/3.
 */

@Injectable()
export class CustomHttpClient implements HttpClientInterface{

  constructor(
    private http:HttpClient,
    private logUtil : LogUtil
  ){
  }

  get(api:string,params?:string): Observable<MsgResult> | any{
    return  this.http.get<MsgResult>(this.wrapToUrl(api,params),this.getNoCahcheRequestOptions())
      .map(res =>this.success(res))
      .catch(error => this.error(error));
  }

  post(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.post<MsgResult>(api,params,this.getRequestOptions())
      .map(res =>this.success(res))
      .catch(error => this.error(error));
  }

  put(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.put<MsgResult>(api,params,this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  delete(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.delete<MsgResult>(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  patch(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.patch<MsgResult>(api,params,this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  head(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.head<MsgResult>(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  options(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.options<MsgResult>(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }
  postWithData(api:string,params?:string): Observable<any> | any{
    return this.http.post<any>(api,params,this.getRequestOptions());
  }

  getFile(api:string,params?:string): Observable<ArrayBuffer>{
    return  this.http.get(this.wrapToUrl(api,params),{
    observe: 'body',
    responseType: 'arraybuffer'
  });
  }

  /**
   * 封装api和param成url
   * @param api
   * @param params
   * @returns {any}
   */
  private wrapToUrl(api:string,params?:string):string{
    if(!!!params){
      return api;
    }
    let url;
    if(api.indexOf("?") != -1){
      let orginParmas =  api.substr(api.indexOf("?") + 1);
      let uri = api.substring(0,api.indexOf("?"));
      url = uri + "?" + (orginParmas.length > 0 ? orginParmas + "&" : "")+ params;
    }else{
      url = api + "?" + params;
    }
    return url;
  }

  /**
   * 处理请求头
   * @returns {RequestOptions}
   */
  private getRequestOptions(){
    let headers = new HttpHeaders()
      .append('Content-Type', 'application/x-www-form-urlencoded')
      .append('X-Requested-With', 'XMLHttpRequest')
    let _defaultOptions = {headers: headers};
    return _defaultOptions;
  }

  /**
   * 构建不缓存数据的请求
   * 修复在IE11下get请求被缓存，导致数据无刷新bug
   * @returns {RequestOptions}
   */
  private getNoCahcheRequestOptions(){
    let headers = new HttpHeaders()
      .set('Content-Type', 'application/x-www-form-urlencoded')
      .set('X-Requested-With', 'XMLHttpRequest' )
      .set("Cache-Control","no-cache")
      .set("Pragma","no-cache")
      .set("Expires","Sat, 01 Jan 2000 00:00:00 GMT")
    let _defaultOptions = {headers: headers};
    return _defaultOptions;
  }
  private getFileRequestOptions():{
    headers?: HttpHeaders;
    observe?: 'body';
    responseType?: 'arraybuffer';
  }{
    let headers = new HttpHeaders()
      .set('Content-Type', 'application/x-www-form-urlencoded')
      .set('X-Requested-With', 'XMLHttpRequest' )
      .set("Cache-Control","no-cache")
      .set("Pragma","no-cache")
      .set("Expires","Sat, 01 Jan 2000 00:00:00 GMT")
    let _defaultOptions = {headers: headers};
    return _defaultOptions;
  }


  /**
   * 成功处理
   * @param res
   * @returns {any}
   */
  private success(res :MsgResult|any){
    let json = res;
    return json;
  }

  /**
   * 失败处理
   * @param error
   * @returns {string}
   */
  private error(err: HttpErrorResponse | any){
    let errMsg: string;
    if (err.error && err.error instanceof Error) {
      errMsg = `${err.code} - ${err.message || ''}`;
    } else {
      errMsg = err.message ? err.message : `${err.status}-${err.error}`;
    }
    this.logUtil.error(errMsg);
    return errMsg;
  }
}
